package middlewareLogExtraction.model;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;

public class DB2Log {
	private final String fileName;
	private List<LogEntry> logEntries;
	private Date date;
	private final String dateInFileNamePattern = "middleware.log.(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})";
	private RegexHelper regexHelper;

	public DB2Log(String file, RegexHelper regexHelper) {
		this.fileName = file;
		this.regexHelper = regexHelper;
		logEntries = new ArrayList<LogEntry>();
		parseLogFile(this.fileName);
		getDateFromFileName();
	}

	private void getDateFromFileName() {
		Matcher matcher = this.regexHelper.regexFind(this.fileName,
				dateInFileNamePattern);
		if (matcher != null) {
			this.date = new Date();
			date.setYear(new Integer(matcher.group(1)).intValue());
			date.setMonth(new Integer(matcher.group(2)).intValue());
			date.setDate(new Integer(matcher.group(3)).intValue());
			date.setHours(new Integer(matcher.group(4)).intValue());
			date.setMinutes(new Integer(matcher.group(5)).intValue());
			date.setSeconds(new Integer(matcher.group(6)).intValue());
		}
	}

	private void parseLogFile(String fileName) {
		File logFile = new File(fileName);
		try {
			BufferedReader br = new BufferedReader(new FileReader(logFile));
			String line;
			while ((line = br.readLine()) != null) {
				logEntries.add(new LogEntry(line, this.regexHelper));
			}
		} catch (FileNotFoundException e) {
			// System.out.println(fileName);
			// e.printStackTrace();
		} catch (IOException e) {
			// e.printStackTrace();
		}

	}

	public String getFileName() {
		return this.fileName;
	}

	public List<LogEntry> getEntries() {
		return this.logEntries;
	}

	public Date getDate() {
		return this.date;
	}

	public int getEntityUpdateOperateCount() {
		int counter = 0;
		for (LogEntry entry : this.logEntries) {
			if (entry.isSpTimingEntryOfSp("GBL2092")) {
				counter++;
			}
		}
		return counter;
	}

	public int getDistinctUserLogonCountOnDate(Date date) {
		HashMap<String, String> map = new HashMap<String, String>();
		for (LogEntry entry : this.logEntries) {
			if (entry.isLoginEntry()) {
				Record rec = RecordFactory.createRecord(entry.getText(),
						this.regexHelper);
				String userName = ((LoginRecord) rec).getUser();
				Date logonDate = entry.getTimeStamp();
				Date nextDay = new Date(date.getYear(), date.getMonth(), date
						.getDate() + 1);
				if (date.before(logonDate) && logonDate.before(nextDay))
					map.put(userName, "");
			}
		}
		return map.size();
	}

	public int GetLogonCountOfUserOnDate(String user, Date date) {
		int counter = 0;
		for (LogEntry entry : this.logEntries) {
			if (entry.isLoginEntry()) {
				Record rec = RecordFactory.createRecord(entry.getText(),
						this.regexHelper);
				String userName = ((LoginRecord) rec).getUser();
				if (userName.equals(user)) {
					Date logonDate = entry.getTimeStamp();
					Date nextDay = new Date(date.getYear(), date.getMonth(),
							date.getDate() + 1);
					if (date.before(logonDate) && logonDate.before(nextDay))
						counter++;
				}
			}
		}
		return counter;
	}

	public int getProductCreationCount(String name) {
		int counter = 0;
		for(LogEntry entry: this.logEntries){
			if(entry.isProductCreationEntry()){
				String productName = ((ProductRecord)RecordFactory.createRecord(entry.getText(), regexHelper)).getName();
				if(productName.equals(name))
					counter++;
			}
		}
		return counter;
	}

	public int getTotalLongRunningSPCount(int thredshold, RecordTimeStrParser timeParser) {
		int counter = 0;
		for(LogEntry entry: this.logEntries){
			if(entry.isSpTimingEntry()){
				String timeStr = ((SPTimingRecord)RecordFactory.createRecord(entry.getText(), regexHelper)).getTime();
				int timeInSec = timeParser.parseTimeStr(timeStr, this.regexHelper).toSeconds();
				if(timeInSec > thredshold)
					counter++;
			}
		}
		return counter;
	}

}
